#include "mainwindow.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#ifdef USE_RTC5
#include "../rtc5/RTC5impl.h"
#elif USE_RTC6
#include "../rtc6/RTC6impl.h"
#endif

#include <QMessageBox>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    uint initDLL = -1;
#ifdef USE_RTC5
    initDLL = init_rtc5_dll();
#elif USE_RTC6
    initDLL = init_rtc6_dll();
#endif
    if (initDLL != 0U)
    {
        if (initDLL & 256U)
        {
            QMessageBox::critical(this, "错误", "DLL等文件版本不匹配,错误码:" + QString::number(initDLL));
            exit(0);
        }
        else if (initDLL & 1U)
        {
            //            QMessageBox::critical(this, "错误", "没有检测到可用卡,错误码:" + QString::number(initDLL));
        }
        else
        {
            QMessageBox::critical(this, "错误", "未知错误,错误码:" + QString::number(initDLL));
        }
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_tableWidget_doubleClicked(const QModelIndex &)
{
    markGoto(false);
}

void MainWindow::on_pushButton_startLoop_clicked(bool checked)
{
    if(checked){
        if(mCards.isEmpty() || mPoints.isEmpty()){
            return;
        }
        markGoto(true);
    }else{
        stop_execution();
    }
}

void MainWindow::markGoto(bool loop)
{
    int c = ui->comboBox_devList->currentIndex();
    if(c < 0 || c >= mCards.size()){
        return;
    }
    int card = c + 1;
    n_set_laser_mode(card, 0);
    n_set_laser_control(card, 0);
    n_config_list(card, 4000, 4000);
    uint list = 1U;
    uint num = n_load_list(card, list, 0U);
    qDebug() << "load list" << card << num;
    if(num != list){
        QMessageBox::critical(this, "错误", "获取列表失败");
        return;
    }
    qDebug() << "load list success";
    n_set_laser_pulses(card, 640, 640);
    n_set_standby(card, 0, 0);
    n_write_da_1(card, 2047.5);
    n_set_mark_speed(card, 1000);
    n_set_jump_speed(card, 1000);
    if(loop){
        for(const QPoint& p : mPoints){
            n_goto_xy(card, p.x(), p.y());
        }
    }else{
        QPoint p = mPoints.at(ui->tableWidget->currentRow());
        n_goto_xy(card, p.x(), p.y());
        n_set_end_of_list(card);
    }
    n_execute_list(card, list);
}

void MainWindow::on_pushButton_startLoop_toggled(bool checked)
{
    ui->pushButton_startLoop->setText(checked ? "停止" : "开始");
}
#ifdef USE_RTC6
QString MainWindow::uint2String(uint data)
{
    char str[64];
    eth_convert_ip_to_string(data,(ULONG_PTR)(str));
    return QString(str);
}
#endif
void MainWindow::on_pushButton_search_clicked()
{
    mCards.clear();
    QStringList errList;
    int foundCards = 0;
#ifdef USE_RTC5
    foundCards = rtc5_count_cards();
#elif USE_RTC6
    foundCards = rtc6_count_cards();
#endif
    for (int card = 1; card <= foundCards; card++)
    {
        uint loadProgram = n_load_program_file(card, nullptr);
        if(loadProgram == 0U){
            uint sn = n_get_serial_number(card);
            mCards.append(QString::number(sn));
        }else{
            errList.append(QString("卡%1 load_program_file失败,错误码%2").arg(card).arg(loadProgram));
        }
    }
#ifdef USE_RTC6
    QString ip = ui->lineEdit_localAddr->text();
    QString mask = "255.255.255.0";
    // Search for and initialize Ethernet boards
    const auto ethSearchIP = eth_convert_string_to_ip(ip.toLocal8Bit().data());
    const auto ethSearchNetmask = eth_convert_string_to_ip(mask.toLocal8Bit().data());
    const auto result = eth_search_cards(ethSearchIP, ethSearchNetmask);
    qDebug() << "Search IP" << ip << mask << result;

    if(result != 0){
        const auto foundEthCards = eth_found_cards();
        qDebug() << "网络RTC6卡数量为：" << foundEthCards;
        for (auto searchCard = 1U; searchCard <= foundEthCards; searchCard++)
        {
            std::array<uint, 16> cardInfo;
            eth_get_card_info_search(searchCard, (uint)cardInfo.data());
            const auto serialNumber = cardInfo[1];
            const auto ipAddress = cardInfo[2];

            int card = eth_assign_card_ip(ipAddress, 0);
            if (card <= 0)
            {
                errList.append(QString("添加网络卡%1失败：,错误码%2").arg(uint2String(ipAddress)).arg(card));
            }else{
                qDebug() << "添加网络卡成功：" << card << serialNumber << uint2String(ipAddress);
                mCards.append(QString::number(serialNumber) + "-" + uint2String(ipAddress));

                uint ac = acquire_rtc(card);
                if(ac == 0U){
                    errList.append(QString("卡%1 acquire_rtc失败，没有权限").arg(card));
                }else if(ac != card){
                    errList.append(QString("acquire_rtc失败，错误码:%1").arg(get_last_error()));
                }else{
                    uint loadProgram = n_load_program_file(card, nullptr);
                    if(loadProgram != 0U){
                        errList.append(QString("卡%1 load_program_file失败,错误码%2").arg(card).arg(loadProgram));
                    }else{
                        qDebug() << QString("卡%1 load_program_file成功").arg(card);
                        n_load_correction_file(card, nullptr, 1, 2);
                    }
                }
            }
        }
    }
#endif
    if(!errList.isEmpty()){
        QMessageBox::critical(this, "错误", errList.join("/n"));
    }
    ui->comboBox_devList->addItems(mCards);
}

void MainWindow::on_pushButton_delete_clicked()
{
    QTableWidgetItem* item = ui->tableWidget->currentItem();
    if(item){
        int row = item->row();
        ui->tableWidget->removeRow(row);
        mPoints.removeAt(row);
    }
}

void MainWindow::on_pushButton_up_clicked()
{
    QTableWidgetItem* item = ui->tableWidget->currentItem();
    if(item){
        int row = item->row();
        if(row <= 0){
            return;
        }
        QList<QTableWidgetItem*> tempList;
        for(int i = 0; i < 2; i++){
            tempList.append(ui->tableWidget->takeItem(row - 1, i));
        }
        for(int i = 0; i < 2; i++){
            ui->tableWidget->setItem(row - 1, i, ui->tableWidget->takeItem(row, i));
        }
        for(int i = 0; i < 2; i++){
            ui->tableWidget->setItem(row, i, tempList.at(i));
        }
        QPoint p = mPoints.at(row - 1);
        mPoints[row - 1] = mPoints.at(row);
        mPoints[row] = p;
    }
}

void MainWindow::on_pushButton_down_clicked()
{
    QTableWidgetItem* item = ui->tableWidget->currentItem();
    if(item){
        int row = item->row();
        if(row >= ui->tableWidget->rowCount() - 1){
            return;
        }
        QList<QTableWidgetItem*> tempList;
        for(int i = 0; i < 2; i++){
            tempList.append(ui->tableWidget->takeItem(row + 1, i));
        }
        for(int i = 0; i < 2; i++){
            ui->tableWidget->setItem(row + 1, i, ui->tableWidget->takeItem(row, i));
        }
        for(int i = 0; i < 2; i++){
            ui->tableWidget->setItem(row, i, tempList.at(i));
        }
        QPoint p = mPoints.at(row + 1);
        mPoints[row + 1] = mPoints.at(row);
        mPoints[row] = p;
    }
}

void MainWindow::on_pushButton_addPoint_clicked()
{
    QPoint p(ui->spinBox_newPointX->value(), ui->spinBox_newPointY->value());
    mPoints.append(p);
    int row = ui->tableWidget->rowCount();
    ui->tableWidget->insertRow(row);

    ui->tableWidget->setItem(row, 0, new QTableWidgetItem(QString::number(p.x())));
    ui->tableWidget->setItem(row, 1, new QTableWidgetItem(QString::number(p.y())));
}

void MainWindow::on_tableWidget_currentItemChanged(QTableWidgetItem *, QTableWidgetItem *)
{
    ui->pushButton_startLoop->setEnabled(ui->tableWidget->rowCount() > 0);
    ui->pushButton_delete->setEnabled(ui->tableWidget->rowCount() > 0);
    ui->pushButton_up->setEnabled(ui->tableWidget->currentRow() > 0);
    ui->pushButton_down->setEnabled(ui->tableWidget->currentRow() < (ui->tableWidget->rowCount() - 1));
}
